package com.shycloud.mido.member.service.impl;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.joy.zebra.common.push.JPushUtils;
import com.shycloud.mido.homework.api.enums.JPushCodeEnum;
import com.shycloud.mido.member.api.entity.*;
import com.shycloud.mido.member.service.MsgMainService;
import com.shycloud.mido.member.service.MsgMemberInfoService;
import org.apache.commons.lang.StringUtils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shycloud.mido.common.api.entity.OrganizationCommon;
import com.shycloud.mido.common.api.mapper.OrganizationCommonMapper;
import com.shycloud.mido.common.core.constant.CommonConstants;
import com.shycloud.mido.common.core.exception.BusinessException;
import com.shycloud.mido.common.security.util.SecurityUtils;
import com.shycloud.mido.common.sms.sdk.CloopenSmsSDK;
import com.shycloud.mido.member.api.vo.SmMemberTeacherApprovalNewVO;
import com.shycloud.mido.member.mapper.MemberMapper;
import com.shycloud.mido.member.mapper.OptOperatorMapper;
import com.shycloud.mido.member.mapper.OrgStudentDetailedMapper;
import com.shycloud.mido.member.mapper.OrgTeacherDetailedMapper;
import com.shycloud.mido.member.mapper.SmMemberNoticeInfoMapper;
import com.shycloud.mido.member.mapper.SmMemberTeacherApprovalNewMapper;
import com.shycloud.mido.member.mapper.SysUserMapper;
import com.shycloud.mido.member.mapper.SysUserRoleMapper;
import com.shycloud.mido.member.service.SmMemberTeacherApprovalNewService;
import com.shycloud.mido.opter.api.entity.OptOperator;

import cn.hutool.core.map.MapUtil;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;

/**
 * 教师认证模块业务实现类
 *
 * @author nianhua.jiang
 * @date 2020/5/21 11:12
 */
@Service
@AllArgsConstructor
public class SmMemberTeacherApprovalNewServiceImpl extends ServiceImpl<SmMemberTeacherApprovalNewMapper, SmMemberTeacherApprovalNew> implements SmMemberTeacherApprovalNewService {

	/** 密码加密 */
	private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();

	/** 站内消息模块 service */
	private MsgMainService msgMainService;
	/** 发送站内消息模块 service */
	private MsgMemberInfoService msgMemberInfoService;

	/** 教师认证 mapper */
	private SmMemberTeacherApprovalNewMapper mapper;
	/** 会员 mapper */
	private MemberMapper memberMapper;
	/** 共通机构 mapper */
	private OrganizationCommonMapper organizationCommonMapper;
	/** 教师详情 mapper */
	private OrgTeacherDetailedMapper orgTeacherDetailedMapper;
	/** 教师模块 mapper */
	private OrgTeacherDetailedMapper teacherDetailedMapper;
	/** 学生模块 mapper */
	private OrgStudentDetailedMapper studentDetailedMapper;
	/** 运营商 mapper */
	private OptOperatorMapper optOperatorMapper;

	/** 后台管理系统 用户 mapper */
	private SysUserMapper sysUserMapper;
	/** 后台管理系统 用户-角色 mapper */
	private SysUserRoleMapper sysUserRoleMapper;

	/** 系统通知模块 mapper */
	private final SmMemberNoticeInfoMapper noticeInfoMapper;
	/** 云通联短信SDK */
	private final CloopenSmsSDK cloopenSmsSDK;

	/** 机构申请短信模板ID */
	private static final String TEACHER_APPLY_TEMPLATE_ID = "642854";
	/** 审核状态：已通过 */
	private final String STATUS_APPROVAL_PASS = "1";


	/**
	 * 分页查询
	 *
	 * @param page
	 * @param name
	 * @param status
	 * @return com.baomidou.mybatisplus.core.metadata.IPage<com.shycloud.mido.member.api.vo.SmMemberTeacherApprovalNewVO>
	 * @author nianhua.jiang
	 * @date 2020/5/20 14:13
	 */
	@Override
	public IPage<SmMemberTeacherApprovalNewVO> getTeacherApprovalPage(Page page, String name, String status, String optId) {
		return mapper.getTeacherApprovalPage(page, name, status, optId);
	}

	/**
	 * 根据ID查询教师认证详细信息
	 *
	 * @param id
	 * @return com.shycloud.mido.member.api.vo.SmMemberTeacherApprovalNewVO
	 * @author nianhua.jiang
	 * @date 2020/5/21 11:10
	 */
	@Override
	public SmMemberTeacherApprovalNewVO getTeacherDetail(Integer id) {
		return mapper.getTeacherDetail(id);
	}

	/**
	 * 通过审核
	 *
	 * @param ids
	 * @return boolean
	 * @author nianhua.jiang
	 * @date 2020/6/16 14:00
	 */
	@SneakyThrows
	@Override
	@Transactional(rollbackFor = Exception.class, timeout = 36000)
	public boolean accept(Integer[] ids) {

		for (Integer id : ids) {
			//更新教师审核状态
			//查询此条教师的审核信息
			SmMemberTeacherApprovalNew teacherApprovalNew = mapper.selectById(id);
			//状态改为【已通过】
			teacherApprovalNew.setStatus(STATUS_APPROVAL_PASS);
			//更新时间
			teacherApprovalNew.setUpdateTime(new Date());
			//更新状态
			mapper.updateById(teacherApprovalNew);

			//更新会员平台认证教师身份
			Member member = memberMapper.selectById(teacherApprovalNew.getMemberId());

			//新建教师工作室
			OrganizationCommon office = new OrganizationCommon();
			//创建时间
			office.setCreateTime(new Date());
			//创建者
			office.setCreateUser(member.getId());
			//在线陪练 -> 开通
			office.setAccompany("1");
			//状态 -> 启用
			office.setStatus("0");
			office.setPhone(member.getPhone());
			//工作室名称
			office.setName(teacherApprovalNew.getStudioName());
			//密码：用户密码
			office.setPsw(member.getPassword());
			//机构码
			office.setCode(getOfficeCode());
			//机构类型：工作室
			office.setIsStudio("1");
			//联系人
			office.setIdName(member.getShowname());
			//新增
			organizationCommonMapper.insert(office);

			//查询插入之后的工作室信息
			OrganizationCommon org = organizationCommonMapper.selectOne(Wrappers.<OrganizationCommon>query().lambda().eq(
					OrganizationCommon::getCode, office.getCode()));
			//新增教师详情
			OrgTeacherDetailed orgTeacherDetailed = new OrgTeacherDetailed();
			//在线陪练 -> 开通
			orgTeacherDetailed.setAccompany("1");
			//创建时间
			orgTeacherDetailed.setCreateTime(new Date());
			//创建人
			orgTeacherDetailed.setCreateUser(member.getId());
			//用户ID
			orgTeacherDetailed.setMemberId(member.getId());
			//机构ID
			orgTeacherDetailed.setOrgId(org.getId());
			//在职状态 -> 在职
			orgTeacherDetailed.setWorkStatus("0");
			//工作性质 -> 全职
			orgTeacherDetailed.setJobNature("1");
			//入职时间
			orgTeacherDetailed.setEntryDate(new Date());
			//首次入职时间
			orgTeacherDetailed.setFirstEntryDate(new Date());
			//教师姓名
			orgTeacherDetailed.setName(teacherApprovalNew.getName());
			//毕业院校
			orgTeacherDetailed.setSchool(teacherApprovalNew.getSchool());
			//教务老师
			orgTeacherDetailed.setEducational("1");
			orgTeacherDetailedMapper.insert(orgTeacherDetailed);

			//是否平台教师认证 0-未认证, 1-已认证, 2-已申请
			member.setIsTeacher("1");
			//机构ID更新
			member.setOrgId(org.getId());
			UpdateWrapper<Member> updateWrapper = new UpdateWrapper<>();
			updateWrapper.eq("id", teacherApprovalNew.getMemberId());
			memberMapper.update(member, updateWrapper);

			//如果改教师已经成为机构管理员, 则触发业务异常
			if (sysUserMapper.selectListAdmin(member.getPhone()).size() > 0) {
				throw new BusinessException("该账号已经是工作室/机构管理员");
			}
			//更新后台角色
			SysUser sysUser = new SysUser();
			//用户名
			sysUser.setUsername(member.getPhone());
			//密码
			sysUser.setPassword(ENCODER.encode("123456"));
			//手机号码
			sysUser.setPhone(member.getPhone());
			//头像
			sysUser.setAvatar(member.getAvatar());
			//部门ID 固定写死 为 25
			sysUser.setDeptId(25);
			//是否锁定
			sysUser.setLockFlag("0");
			//逻辑删除
			sysUser.setDelFlag("0");
			//创建时间
			sysUser.setCreateTime(new Date());
			//新增后台管理的用户信息
			int result = sysUserMapper.insertSysUser(sysUser);

			//插入用户-角色关系表
			SysUserRole sysUserRole = new SysUserRole();
			//userId
			sysUserRole.setUserId(sysUser.getUserId());
			//角色ID - 固定为机构角色
			sysUserRole.setRoleId(19);
			//新增用户角色关系表
			sysUserRoleMapper.insertRole(sysUserRole);

			// ============ 2021-04-12 新增通知需求，教师认证成功后发送通知 ==================//
			SmMemberNoticeInfo noticeInfo = new SmMemberNoticeInfo();
			//通知时间
			noticeInfo.setCreateTime(new Date());
			//用户ID
			noticeInfo.setMemberId(member.getId());
			//状态 - 未领取
			noticeInfo.setStatus("0");
			//通知ID
			noticeInfo.setNoticeId(1);
			//新增教师认证
			noticeInfoMapper.insert(noticeInfo);
			//========================================================================//

			//发送短信通知
			String returnCode = this.cloopenSmsSDK.sendTemplateSMS(teacherApprovalNew.getPhone(), TEACHER_APPLY_TEMPLATE_ID, null).get("statusCode").toString();
			//推送
			try {
				JPushUtils.sendJPush("教师认证成功", "您的教师认证已通过，可以添加学生上课和布置作业了", member.getClientId());
				// 新增站内信
				// String msgId = addMsg("教师认证成功", "您的教师认证已通过，可以添加学生上课和布置作业了", member.getClientId(), "", "", "1");
				String msgId = "teacher_approval_success";
				//发送站内信给教师
				msgMemberInfoService.sendMsg(msgId, "sys", member.getId());
				//告知APP请求 getMsgApp 接口
				JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_APP_HOMEPAGE_VIEW.getType(),
						member.getClientId(), "告知APP请求 getMsgApp 接口");
			} catch (Exception e) {
				return true;
			}
		}
		return true;
	}

	/**
	 * 创建机构密码
	 *
	 * @param
	 * @return java.lang.String
	 * @author nianhua.jiang
	 * @date 2020/5/21 15:14
	 */
	private String getOfficeCode() {

		boolean flg = true;
		String code = "";
		while (flg) {
			//随机6位机构码
			code = (int) ((Math.random() * 9 + 1) * 100000) + "";
			//判断机构码是否重复
			OrganizationCommon org = organizationCommonMapper.selectOne(Wrappers.<OrganizationCommon>query().lambda().eq(
					OrganizationCommon::getCode, code));

			//不存在机构码，跳出循环
			if (org == null) {
				flg = false;
			}
		}
		//返回随机生成的机构码
		return code;
	}

	/**
	 * 查询此教师是否为平台认证教师
	 *
	 * @param
	 * @return java.util.Map<java.lang.String, java.lang.Object>
	 * @author nianhua.jiang
	 * @date 2020/6/16 18:17
	 */
	@Override
	public Map<String, Object> checkTeacherApproval(String memberId) {

		//初始化结果Map
		Map<String, Object> resultMap = MapUtil.newHashMap();

		//设置初始状态为 【未审核】
		resultMap.put("status", "-1");

		//查询 teacher 表看是否有数据
		List<OrgTeacherDetailed> orgTeacherDetaileds = teacherDetailedMapper.selectList(new QueryWrapper<OrgTeacherDetailed>()
				.eq("member_id", memberId)
				.and(x -> x.eq("del_flag", "0")));

		if (orgTeacherDetaileds.size() > 0) {
			//已认证
			resultMap.put("status", STATUS_APPROVAL_PASS);
		}

		//查询教师申请表，取出其状态
		else {
			SmMemberTeacherApprovalNew smMemberTeacherApprovalNew = mapper.selectOne(new QueryWrapper<SmMemberTeacherApprovalNew>().eq(SmMemberTeacherApprovalNew.COL_MEMBER_ID, memberId));
			if (smMemberTeacherApprovalNew != null && StringUtils.isNotBlank(smMemberTeacherApprovalNew.getStatus())) {
				//状态 0-审核中, 1-已通过, 2-已驳回
				resultMap.put("status", smMemberTeacherApprovalNew.getStatus());
			}
		}

		SmMemberTeacherApprovalNewVO teacherApprovalNewVO = mapper.getTeacherDetailApp(memberId);

		if (teacherApprovalNewVO == null) {
			teacherApprovalNewVO = new SmMemberTeacherApprovalNewVO();
		}

		//将【教学成果】的字符串分割成数组
		if (teacherApprovalNewVO != null && StringUtils.isNotBlank(teacherApprovalNewVO.getAchievementPic())) {
			String[] arr = teacherApprovalNewVO.getAchievementPic().split(",");
			teacherApprovalNewVO.setImgList(arr);
		}

		resultMap.put("teacherApprovalDetail", teacherApprovalNewVO);

		return resultMap;
	}

	/**
	 * 认证教师
	 *
	 * @param smMemberTeacherApprovalNewVO
	 * @return void
	 * @author nianhua.jiang
	 * @date 2020/8/12 18:30
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveTeacherApproval(SmMemberTeacherApprovalNewVO smMemberTeacherApprovalNewVO) {

		//先判断此用户是否存在于学生表中
		String memberId = SecurityUtils.getMember().getId();

		OrgStudentDetailed studentDetailed = studentDetailedMapper.selectOne(new QueryWrapper<OrgStudentDetailed>()
				.eq(OrgStudentDetailed.COL_MEMBER_ID, memberId)
				.and(x -> x.eq(OrgStudentDetailed.COL_DEL_FLAG, CommonConstants.STATUS_NORMAL)));

		if (studentDetailed != null && studentDetailed.getOrgId() != 0) {
			throw new BusinessException("该学生已经与其他教师绑定，无法申请教师");
		}

		//******************** 2021-04-07 nianhua.jiang ADD 认证教师时自动归属运营商 **********************//
//		Member member = memberMapper.selectById(memberId);
//		//先判断此用户（学生）是否绑定了某个运营商
//		if (member.getOptId() == null || member.getOptId() == 999999) {
//			//再判断认证教师再此地区是否存在运营商
//			String cityName = smMemberTeacherApprovalNewVO.getCityName();
//			//查询此地是否有运营商
//			List<OptOperator> opts = optOperatorMapper.selectList(new QueryWrapper<OptOperator>().eq("city", cityName));
//			if (opts.size() == 0) {
//				//归属总部
//			} else {
//				member.setOptId(999999);
//				memberMapper.updateById(member);
//			}
//		}
		//******************** 2021-04-07 nianhua.jiang ADD 认证教师时自动归属运营商 **********************//

		SmMemberTeacherApprovalNew smMemberTeacherApprovalNew = new SmMemberTeacherApprovalNew();

		//获取前端传过来的图片地址集合
		String[] imgArr = smMemberTeacherApprovalNewVO.getImgList();
		StringBuffer stringBuffer = new StringBuffer();
		//将图片集合整合成以逗号形式分割的字符串
		if (imgArr != null) {
			for (String s : imgArr) {
				stringBuffer.append(s).append(",");
			}
		}
		//将最后一个逗号去掉
		String keywordStr = StringUtils.EMPTY;
		if (stringBuffer.length() > 0) {
			keywordStr = stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString();
		}

		//id不为空，则更新操作
		if (smMemberTeacherApprovalNewVO.getId() != null) {
			//获取认证信息
			smMemberTeacherApprovalNew = mapper.selectById(smMemberTeacherApprovalNewVO.getId());
			//教学成果展示的图片
			smMemberTeacherApprovalNew.setAchievementPic(keywordStr);
			//教龄
			smMemberTeacherApprovalNew.setTeachYear(smMemberTeacherApprovalNewVO.getTeachYear());
			//毕业员校
			smMemberTeacherApprovalNew.setSchool(smMemberTeacherApprovalNewVO.getSchool());
			//如果状态为【已驳回】
			if ("2".equals(smMemberTeacherApprovalNew.getStatus())) {
				//状态改为【未审核】
				smMemberTeacherApprovalNew.setStatus("0");
			}

			//修改教师认证表的同时，修改教师主表的毕业院校信息
			OrgTeacherDetailed orgTeacherDetailed = teacherDetailedMapper.selectOne(new QueryWrapper<OrgTeacherDetailed>()
					.eq(OrgTeacherDetailed.COL_MEMBER_ID, memberId)
					.and(x -> x.eq(OrgTeacherDetailed.COL_DEL_FLAG, "0")));
			if (orgTeacherDetailed != null) {
				orgTeacherDetailed.setSchool(smMemberTeacherApprovalNewVO.getSchool());
				teacherDetailedMapper.updateById(orgTeacherDetailed);
			}
			//更新操作
			return mapper.updateById(smMemberTeacherApprovalNew) == 1 ? true : false;
		}

		//id为空，新增教师认证信息
		else {
			//member_id
			smMemberTeacherApprovalNew.setMemberId(SecurityUtils.getMember().getId());
			//教学成果展示的图片
			smMemberTeacherApprovalNew.setAchievementPic(keywordStr);
			//电话号
			smMemberTeacherApprovalNew.setPhone(SecurityUtils.getMember().getPhone());
			//更新时间
			smMemberTeacherApprovalNew.setUpdateTime(new Date());
			//创建时间
			smMemberTeacherApprovalNew.setCreateTime(new Date());
			//教龄
			smMemberTeacherApprovalNew.setTeachYear(smMemberTeacherApprovalNewVO.getTeachYear());
			//毕业员校
			smMemberTeacherApprovalNew.setSchool(smMemberTeacherApprovalNewVO.getSchool());
			//教师昵称
			smMemberTeacherApprovalNew.setName(smMemberTeacherApprovalNewVO.getName());
			//工作室名称
			smMemberTeacherApprovalNew.setStudioName(smMemberTeacherApprovalNewVO.getStudioName());
			//省编号
			smMemberTeacherApprovalNew.setProvinceCode(smMemberTeacherApprovalNewVO.getProvinceCode());
			//省名称
			smMemberTeacherApprovalNew.setProvinceName(smMemberTeacherApprovalNewVO.getProvinceName());
			//市编号
			smMemberTeacherApprovalNew.setCityCode(smMemberTeacherApprovalNewVO.getCityCode());
			//市名称
			smMemberTeacherApprovalNew.setCityName(smMemberTeacherApprovalNewVO.getCityName());
			//追加
			return mapper.insert(smMemberTeacherApprovalNew) == 1 ? true : false;
		}
	}

	@Override
	public boolean sendMsg(String memberId) {

		Member member = memberMapper.selectById(memberId);
		//获取推送ID
		String regId = member.getClientId();

		//添加消息
		//String msgId = addMsg("教师认证失败", "抱歉，您的教师认证申请未能通过审核，点击消息，跳转至”个人设置-教师认证页面“", regId, "", "", "2");
		String msgId = "teacher_approval_fail";
		//发送站内消息
		msgMemberInfoService.sendMsg(msgId, "sys", member.getId());

		//推送消息
		JPushUtils.sendJPush("教师认证失败", "抱歉，您的教师认证申请未能通过审核", regId);
		//推送消息告知 APP
		JPushUtils.sendJMessage(JPushCodeEnum.J_PUSH_APP_HOMEPAGE_VIEW.getType(), regId, "请求 getMsgApp 接口");

		return true;
	}

	private String addMsg(String title, String message, String regId, String pushRespCode, String pushRespMsg, String triggerTo) {

		MsgMain msgMain = new MsgMain();
		//给教师发送
		msgMain.setTriggerTo(triggerTo);
		//来自学生完成的作业 - 系统自动推送
		msgMain.setTriggerFrom("0");
		//消息下发的场合：教师认证成功
		msgMain.setPoint("3");
		//不可修改
		msgMain.setModify("0");
		//自动推送
		msgMain.setMode("1");
		//个人
		msgMain.setRangeType("1");
		//有效数据
		msgMain.setDelFlag("0");
		//创建时间
		msgMain.setCreateTime(LocalDateTime.now());
		//消息类型：文本
		msgMain.setMsgType("0");
		//发送时间
		msgMain.setActualPubDatetime(LocalDateTime.now());
		//创建人-> 系统
		msgMain.setCreateUser("sys");
		//消息内容
		msgMain.setMessage(message);
		//发布时间
		msgMain.setPubDatetime(LocalDateTime.now());
		//极光推送唯一ID
		msgMain.setPushId(regId);
		//极光推送返回 code
		msgMain.setPushRespCode(pushRespCode);
		//极光推送返回 msg
		msgMain.setPushRespMsg(pushRespMsg);
		//TODO 推送成功
		msgMain.setPushStatus("0");
		//推送时间
		msgMain.setPushTime(LocalDateTime.now());
		//标题
		msgMain.setTitle(title);
		//系统消息
		msgMain.setType("0");

		return msgMainService.addSysMsg(msgMain);
	}

}
